#ifndef _DOT_HPP
#define	_DOT_HPP

#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <boost/format.hpp>
#include "dotable.hpp"
#include "util.hpp"
#include "lex_cast.h"

using namespace std;
class dotable;


class dotAttrib {
public:
	string	toStr();

	template <typename T>
	void	setAttr(string attr, T val) {
		using boost::str;
		using boost::format;
		attributes[attr] = str(format("\"%1%\"") % val);	// quotes omkring val
	}

private:
	typedef map<string,string> map_ss;
	map_ss attributes;
};

class dotNode : protected dotAttrib {
public:
	dotNode(dotable *n);
	dotNode(const string& special);
	string		toString();

	template <typename W>
	dotNode&	Set(string attr, W val) {
		this->setAttr(attr, val);
		return *this;
	}

private:
	string uid;	// Kun noder har en unik ID. Og den er ikke en property. SELVE noden.
};

////////////////////////////////////////////////////////////////////////////////

class dotKant : private dotAttrib {
public:
	dotKant(dotable *from, dotable *to);
	string		toString();

	template <typename W>
	dotKant&	Set(string attr, W val) {
		this->setAttr(attr, val);
		return *this;
	}

private:
	string uidFrom;
	string uidTo;
};

////////////////////////////////////////////////////////////////////////////////

class dot {
public:
	dot();
	dotNode&	addNode(dotable *n);
	dotKant&	addKant(dotable *from, dotable *to);
	dotNode&	nodeDefault();
	dotNode&	kantDefault();	// nej, det er ikke en typo, at dotNode& returneres
	void		writeDOTfile(const char *fPath);
	string		toString();

private:
	/*	Graphviz tillader at angive defaults for noder og kanter.
	 *	Noder og kanter arver disse default-attributter, og kan override dem,
	 *	da nodernes/kanternes egne attributter tager præcedens.
	 *	Graphviz bruger samme format som dotNode til at angive disse defaults.
	 */
	dotNode node_defaults;		// Angiver graphviz-defaults for noder
	dotNode edge_defaults;		// Angiver graphviz-defaults for kanter
	
	vector<dotNode> dotNoder;	// Indeholder alle noder
	vector<dotKant> dotKanter;	// Indeholde alle kanter
};


#endif	/* _DOT_HPP */
